package org.lc.stk.web.response;

import com.fasterxml.jackson.annotation.JsonInclude;

import io.swagger.v3.oas.annotations.media.Schema;

/**
 * 通用API响应类
 *
 * <p>该类用于封装API的响应结果，包含以下信息：</p>
 * <ul>
 *   <li>success: 请求是否成功</li>
 *   <li>data: 响应数据</li>
 *   <li>code: 错误代码</li>
 *   <li>message: 错误信息</li>
 *   <li>pageInfo: 分页信息</li>
 * </ul>
 *
 * @param <T> 响应数据的类型
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "API响应")
public class ApiResponse<T> {
    
    @Schema(description = "是否成功", example = "true")
    private boolean success;
    
    @Schema(description = "响应数据")
    private T data;
    
    @Schema(description = "错误代码", example = "BIZ_ERROR")
    private String code;
    
    @Schema(description = "错误信息", example = "操作失败")
    private String message;
    
    @Schema(description = "分页信息")
    private PageInfo pageInfo;
    
    /**
     * 创建一个成功的响应，不包含数据。
     *
     * @param <T> 响应数据的类型
     * @return 成功的ApiResponse实例
     */
    public static <T> ApiResponse<T> success() {
        return new ApiResponse<>(true);
    }
    
    /**
     * 创建一个成功的响应，包含数据。
     *
     * @param <T> 响应数据的类型
     * @param data 响应数据
     * @return 成功的ApiResponse实例
     */
    public static <T> ApiResponse<T> success(T data) {
        return new ApiResponse<>(true, data);
    }
    
    /**
     * 创建一个成功的响应，包含数据和分页信息。
     *
     * @param <T> 响应数据的类型
     * @param data 响应数据
     * @param pageInfo 分页信息
     * @return 成功的ApiResponse实例
     */
    public static <T> ApiResponse<T> success(T data, PageInfo pageInfo) {
        ApiResponse<T> response = new ApiResponse<>(true, data);
        response.setPageInfo(pageInfo);
        return response;
    }

    public static <T> ApiResponse<T> success(T data, String message) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setSuccess(true);
        response.setData(data);
        response.setMessage(message);
        return response;
    }
    
    /**
     * 创建一个错误的响应，包含错误代码和错误信息。
     *
     * @param <T> 响应数据的类型
     * @param code 错误代码
     * @param message 错误信息
     * @return 错误的ApiResponse实例
     */
    public static <T> ApiResponse<T> error(String code, String message) {
        return new ApiResponse<>(false, code, message);
    }
    
    /**
     * 创建一个错误的响应，包含错误信息。
     *
     * @param <T> 响应数据的类型
     * @param message 错误信息
     * @return 错误的ApiResponse实例
     */
    public static <T> ApiResponse<T> error(String message) {
        return new ApiResponse<>(false, "ERROR", message);
    }
    
    public ApiResponse() {
    }
    
    public ApiResponse(boolean success) {
        this.success = success;
    }
    
    public ApiResponse(boolean success, T data) {
        this.success = success;
        this.data = data;
    }
    
    public ApiResponse(boolean success, String code, String message) {
        this.success = success;
        this.code = code;
        this.message = message;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public PageInfo getPageInfo() {
        return pageInfo;
    }

    public void setPageInfo(PageInfo pageInfo) {
        this.pageInfo = pageInfo;
    }

    /**
     * 分页信息类
     *
     * <p>该类用于封装分页相关的信息，包括：</p>
     * <ul>
     *   <li>pageNumber: 当前页码</li>
     *   <li>pageSize: 每页大小</li>
     *   <li>totalElements: 总记录数</li>
     *   <li>totalPages: 总页数</li>
     * </ul>
     */
    @Schema(description = "分页信息")
    public static class PageInfo {
        @Schema(description = "当前页码", example = "1")
        private int pageNumber;
        
        @Schema(description = "每页大小", example = "10")
        private int pageSize;
        
        @Schema(description = "总记录数", example = "100")
        private long totalElements;
        
        @Schema(description = "总页数", example = "10")
        private int totalPages;

        public PageInfo() {
        }

        public PageInfo(int pageNumber, int pageSize, long totalElements, int totalPages) {
            this.pageNumber = pageNumber;
            this.pageSize = pageSize;
            this.totalElements = totalElements;
            this.totalPages = totalPages;
        }

        public int getPageNumber() {
            return pageNumber;
        }

        public void setPageNumber(int pageNumber) {
            this.pageNumber = pageNumber;
        }

        public int getPageSize() {
            return pageSize;
        }

        public void setPageSize(int pageSize) {
            this.pageSize = pageSize;
        }

        public long getTotalElements() {
            return totalElements;
        }

        public void setTotalElements(long totalElements) {
            this.totalElements = totalElements;
        }

        public int getTotalPages() {
            return totalPages;
        }

        public void setTotalPages(int totalPages) {
            this.totalPages = totalPages;
        }
    }
}